using UnityEngine;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.IO;

public class DateTimePickerBuilder
{
    [MenuItem("Tools/DateTimePicker/Create Demo Scene")]
    public static void CreateDemoScene()
    {
        // New empty scene
        EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);

        // Ensure directories
        Directory.CreateDirectory("Assets/Scenes");
        Directory.CreateDirectory("Assets/Prefabs");
        Directory.CreateDirectory("Assets/Scripts");
        Directory.CreateDirectory("Assets/Editor");

        // EventSystem
        var es = new GameObject("EventSystem", typeof(EventSystem), typeof(StandaloneInputModule));

        // Canvas
        var canvasGO = new GameObject("Canvas", typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster));
        Canvas canvas = canvasGO.GetComponent<Canvas>();
        canvas.renderMode = RenderMode.ScreenSpaceOverlay;
        var cs = canvasGO.GetComponent<CanvasScaler>();
        cs.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
        cs.referenceResolution = new Vector2(1920, 1080);

        // Panel
        var panel = CreateUI("DateTimePickerPanel", canvasGO.transform);
        var panelImage = panel.AddComponent<Image>();
        panelImage.color = new Color(0.95f, 0.95f, 0.95f);
        var panelRt = panel.GetComponent<RectTransform>();
        panelRt.sizeDelta = new Vector2(900, 420);
        panelRt.anchoredPosition = Vector2.zero;

        // Header
        var header = CreateUI("Header", panel.transform);
        var headerRt = header.GetComponent<RectTransform>();
        headerRt.anchorMin = new Vector2(0, 1);
        headerRt.anchorMax = new Vector2(1, 1);
        headerRt.pivot = new Vector2(0.5f, 1);
        headerRt.sizeDelta = new Vector2(0, 60);
        headerRt.anchoredPosition = new Vector2(0, 0);

        var title = CreateText("TitleText", "请选择时间", header.transform);
        title.GetComponent<Text>().fontSize = 22;
        var titleRt = title.GetComponent<RectTransform>();
        titleRt.anchorMin = titleRt.anchorMax = new Vector2(0.5f, 0.5f);
        titleRt.anchoredPosition = new Vector2(-30, -10);

        var closeBtn = CreateButton("CloseButton", "X", header.transform);
        var closeRt = closeBtn.GetComponent<RectTransform>();
        closeRt.anchorMin = closeRt.anchorMax = new Vector2(1, 0.5f);
        closeRt.sizeDelta = new Vector2(40, 30);
        closeRt.anchoredPosition = new Vector2(-20, -10);

        // Top selected text
        var topText = CreateText("TopSelectedText", "当前选择时间: 2025-11-18 03:45", panel.transform);
        var topRt = topText.GetComponent<RectTransform>();
        topRt.anchorMin = topRt.anchorMax = new Vector2(0.5f, 1);
        topRt.anchoredPosition = new Vector2(0, -50);
        topText.GetComponent<Text>().fontSize = 18;
        topText.GetComponent<Text>().alignment = TextAnchor.MiddleCenter;

        // Body
        var body = CreateUI("Body", panel.transform);
        var bodyRt = body.GetComponent<RectTransform>();
        bodyRt.anchorMin = new Vector2(0, 0);
        bodyRt.anchorMax = new Vector2(1, 1);
        bodyRt.pivot = new Vector2(0.5f, 0.5f);
        bodyRt.sizeDelta = new Vector2(-40, -140);
        bodyRt.anchoredPosition = new Vector2(0, -10);

        // Left Calendar
        var left = CreateUI("LeftCalendar", body.transform);
        var leftRt = left.GetComponent<RectTransform>();
        leftRt.anchorMin = new Vector2(0, 0);
        leftRt.anchorMax = new Vector2(0.6f, 1);
        leftRt.offsetMin = new Vector2(10, 10);
        leftRt.offsetMax = new Vector2(-10, -10);

        // Month Nav
        var monthNav = CreateUI("MonthNav", left.transform);
        var mRt = monthNav.GetComponent<RectTransform>();
        mRt.anchorMin = new Vector2(0, 1);
        mRt.anchorMax = new Vector2(1, 1);
        mRt.pivot = new Vector2(0.5f, 1);
        mRt.sizeDelta = new Vector2(0, 40);

        var prevBtn = CreateButton("PrevBtn", "<", monthNav.transform);
        var prevRt = prevBtn.GetComponent<RectTransform>();
        prevRt.anchorMin = prevRt.anchorMax = new Vector2(0, 0.5f);
        prevRt.sizeDelta = new Vector2(40, 30);
        prevRt.anchoredPosition = new Vector2(30, 0);

        var monthText = CreateText("MonthText", "2025 - 11", monthNav.transform);
        monthText.GetComponent<Text>().fontSize = 18;
        monthText.GetComponent<Text>().alignment = TextAnchor.MiddleCenter;

        var nextBtn = CreateButton("NextBtn", ">", monthNav.transform);
        var nextRt = nextBtn.GetComponent<RectTransform>();
        nextRt.anchorMin = nextRt.anchorMax = new Vector2(1, 0.5f);
        nextRt.sizeDelta = new Vector2(40, 30);
        nextRt.anchoredPosition = new Vector2(-30, 0);

        // WeekHeader
        var weekHeader = CreateUI("WeekHeader", left.transform);
        var whRt = weekHeader.GetComponent<RectTransform>();
        whRt.anchorMin = new Vector2(0, 1);
        whRt.anchorMax = new Vector2(1, 1);
        whRt.sizeDelta = new Vector2(0, 30);
        whRt.anchoredPosition = new Vector2(0, -50);

        string[] weekNames = new string[] { "日", "一", "二", "三", "四", "五", "六" };
        for (int i = 0; i < 7; i++)
        {
            var w = CreateText("W" + i, weekNames[i], weekHeader.transform);
            var rt = w.GetComponent<RectTransform>();
            rt.sizeDelta = new Vector2(60, 30);
            rt.anchoredPosition = new Vector2(-210 + i * 70, 0);
            w.GetComponent<Text>().alignment = TextAnchor.MiddleCenter;
        }

        // CalendarGrid
        var gridGO = CreateUI("CalendarGrid", left.transform);
        var gridRt = gridGO.GetComponent<RectTransform>();
        gridRt.anchorMin = new Vector2(0, 0);
        gridRt.anchorMax = new Vector2(1, 1);
        gridRt.offsetMin = new Vector2(10, 10);
        gridRt.offsetMax = new Vector2(-10, -100);

        var grid = gridGO.AddComponent<GridLayoutGroup>();
        grid.constraint = GridLayoutGroup.Constraint.FixedColumnCount;
        grid.constraintCount = 7;
        grid.cellSize = new Vector2(60, 40);
        grid.spacing = new Vector2(6, 6);
        grid.childAlignment = TextAnchor.UpperLeft;
        grid.padding = new RectOffset(4, 4, 4, 4);

        // RightTimePickers (container for hour & minute side-by-side)
        var right = CreateUI("RightTimePickers", body.transform);
        var rightRt = right.GetComponent<RectTransform>();
        rightRt.anchorMin = new Vector2(0.6f, 0);
        rightRt.anchorMax = new Vector2(1, 1);
        rightRt.offsetMin = new Vector2(10, 10);
        rightRt.offsetMax = new Vector2(-10, -10);

        // Hour container (left part of right)
        var hourContainer = CreateUI("HourContainer", right.transform);
        var hourCr = hourContainer.GetComponent<RectTransform>();
        hourCr.anchorMin = new Vector2(0, 0);
        hourCr.anchorMax = new Vector2(0.5f, 1);
        hourCr.offsetMin = new Vector2(5, 5);
        hourCr.offsetMax = new Vector2(-5, -5);

        // Minute container (right part)
        var minuteContainer = CreateUI("MinuteContainer", right.transform);
        var minuteCr = minuteContainer.GetComponent<RectTransform>();
        minuteCr.anchorMin = new Vector2(0.5f, 0);
        minuteCr.anchorMax = new Vector2(1, 1);
        minuteCr.offsetMin = new Vector2(5, 5);
        minuteCr.offsetMax = new Vector2(-5, -5);

        // Hour ScrollRect
        var hourObj = CreateUI("HourPicker", hourContainer.transform);
        var hourRt = hourObj.GetComponent<RectTransform>();
        hourRt.anchorMin = new Vector2(0, 0);
        hourRt.anchorMax = new Vector2(1, 1);
        hourRt.offsetMin = Vector2.zero;
        hourRt.offsetMax = Vector2.zero;
        var hourScroll = hourObj.AddComponent<ScrollRect>();
        hourScroll.vertical = true;
        hourScroll.horizontal = false;

        // Hour viewport & content
        var hourViewport = CreateUI("Viewport", hourObj.transform);
        var vpImg = hourViewport.AddComponent<Image>(); vpImg.color = Color.clear;
        var vpRt = hourViewport.GetComponent<RectTransform>();
        vpRt.anchorMin = new Vector2(0, 0);
        vpRt.anchorMax = new Vector2(1, 1);
        vpRt.offsetMin = Vector2.zero;
        vpRt.offsetMax = Vector2.zero;
        hourViewport.AddComponent<RectMask2D>();

        var hourContent = CreateUI("Content", hourViewport.transform);
        var hcRt = hourContent.GetComponent<RectTransform>();
        hcRt.anchorMin = new Vector2(0, 1);
        hcRt.anchorMax = new Vector2(1, 1);
        hcRt.pivot = new Vector2(0.5f, 1f);
        hcRt.anchoredPosition = Vector2.zero;

        var vlayout = hourContent.AddComponent<VerticalLayoutGroup>();
        vlayout.childControlHeight = false;
        vlayout.childControlWidth = true;
        vlayout.childForceExpandHeight = false;
        vlayout.spacing = 2;

        hourScroll.viewport = vpRt;
        hourScroll.content = hcRt;

        // Minute ScrollRect
        var minuteObj = CreateUI("MinutePicker", minuteContainer.transform);
        var minuteRt = minuteObj.GetComponent<RectTransform>();
        minuteRt.anchorMin = new Vector2(0, 0);
        minuteRt.anchorMax = new Vector2(1, 1);
        minuteRt.offsetMin = Vector2.zero;
        minuteRt.offsetMax = Vector2.zero;
        var minuteScroll = minuteObj.AddComponent<ScrollRect>();
        minuteScroll.vertical = true;
        minuteScroll.horizontal = false;

        // Minute viewport & content
        var minuteViewport = CreateUI("Viewport", minuteObj.transform);
        var mvImg = minuteViewport.AddComponent<Image>(); mvImg.color = Color.clear;
        var mvRt = minuteViewport.GetComponent<RectTransform>();
        mvRt.anchorMin = new Vector2(0, 0);
        mvRt.anchorMax = new Vector2(1, 1);
        mvRt.offsetMin = Vector2.zero;
        mvRt.offsetMax = Vector2.zero;
        minuteViewport.AddComponent<RectMask2D>();

        var minuteContent = CreateUI("Content", minuteViewport.transform);
        var mcRt = minuteContent.GetComponent<RectTransform>();
        mcRt.anchorMin = new Vector2(0, 1);
        mcRt.anchorMax = new Vector2(1, 1);
        mcRt.pivot = new Vector2(0.5f, 1f);
        mcRt.anchoredPosition = Vector2.zero;

        var vlayout2 = minuteContent.AddComponent<VerticalLayoutGroup>();
        vlayout2.childControlHeight = false;
        vlayout2.childControlWidth = true;
        vlayout2.childForceExpandHeight = false;
        vlayout2.spacing = 2;

        minuteScroll.viewport = mvRt;
        minuteScroll.content = mcRt;

        // Bottom buttons
        var bottom = CreateUI("BottomButtons", panel.transform);
        var bottomRt = bottom.GetComponent<RectTransform>();
        bottomRt.anchorMin = new Vector2(0, 0);
        bottomRt.anchorMax = new Vector2(1, 0);
        bottomRt.pivot = new Vector2(0.5f, 0);
        bottomRt.sizeDelta = new Vector2(0, 60);
        bottomRt.anchoredPosition = new Vector2(0, 10);

        var nowBtn = CreateButton("NowButton", "此刻", bottom.transform);
        var cancelBtn = CreateButton("CancelButton", "取消", bottom.transform);
        var confirmBtn = CreateButton("ConfirmButton", "确定", bottom.transform);

        // Create DayCell prefab
        var dayCell = CreateUI("DayCellPrefab", null);
        var dayImg = dayCell.AddComponent<Image>();
        dayImg.color = Color.white;
        var dayBtn = dayCell.AddComponent<Button>();
        var dayText = CreateText("DayText", "1", dayCell.transform);
        dayText.GetComponent<Text>().alignment = TextAnchor.MiddleCenter;
        var dRt = dayCell.GetComponent<RectTransform>();
        dRt.sizeDelta = new Vector2(60, 40);

        string dayPrefabPath = "Assets/Prefabs/DayCell.prefab";
        PrefabUtility.SaveAsPrefabAsset(dayCell, dayPrefabPath);
        Object.DestroyImmediate(dayCell);

        // Create TimeItem prefab
        var timeItem = CreateUI("TimeItemPrefab", null);
        var timeBtn = timeItem.AddComponent<Button>();
        var timeText = CreateText("Label", "00", timeItem.transform);
        timeText.GetComponent<Text>().alignment = TextAnchor.MiddleCenter;
        var tiRt = timeItem.GetComponent<RectTransform>();
        tiRt.sizeDelta = new Vector2(0, 40);

        string timePrefabPath = "Assets/Prefabs/TimeItem.prefab";
        PrefabUtility.SaveAsPrefabAsset(timeItem, timePrefabPath);
        Object.DestroyImmediate(timeItem);

        // Attach CalendarController to non-visible GO
        var calendarGO = CreateUI("CalendarController", panel.transform);
        calendarGO.SetActive(false);
        var cal = calendarGO.AddComponent<CalendarController>();
        cal.monthText = monthText.GetComponent<Text>();
        cal.gridParent = gridGO.transform;
        cal.dayPrefab = AssetDatabase.LoadAssetAtPath<GameObject>(dayPrefabPath);
        cal.prevBtn = prevBtn.GetComponent<Button>();
        cal.nextBtn = nextBtn.GetComponent<Button>();
        cal.topSelectedText = topText.GetComponent<Text>();

        // Attach DateTimePicker to panel
        var dtPicker = panel.AddComponent<DateTimePicker>();
        dtPicker.calendar = cal;
        dtPicker.topSelectedText = topText.GetComponent<Text>();
        dtPicker.confirmBtn = confirmBtn.GetComponent<Button>();
        dtPicker.cancelBtn = cancelBtn.GetComponent<Button>();
        dtPicker.nowBtn = nowBtn.GetComponent<Button>();

        // Attach TimePickerScroller components and assign refs
        var hourScroller = hourObj.AddComponent<TimePickerScroller>();
        hourScroller.scrollRect = hourScroll;
        hourScroller.content = hcRt;
        hourScroller.timeItemPrefab = AssetDatabase.LoadAssetAtPath<GameObject>(timePrefabPath);
        hourScroller.maxValue = 23;
        hourScroller.step = 1;
        hourScroller.itemHeight = 40f;
        hourScroller.twoDigits = true;
        hourScroller.isHour = true;
        hourScroller.parentPicker = dtPicker;

        var minuteScroller = minuteObj.AddComponent<TimePickerScroller>();
        minuteScroller.scrollRect = minuteScroll;
        minuteScroller.content = mcRt;
        minuteScroller.timeItemPrefab = AssetDatabase.LoadAssetAtPath<GameObject>(timePrefabPath);
        minuteScroller.maxValue = 59;
        minuteScroller.step = 1;
        minuteScroller.itemHeight = 40f;
        minuteScroller.twoDigits = true;
        minuteScroller.isHour = false;
        minuteScroller.parentPicker = dtPicker;

        dtPicker.hourPicker = hourScroller;
        dtPicker.minutePicker = minuteScroller;

        // Save scene
        string scenePath = "Assets/Scenes/DateTimePickerDemo.unity";
        EditorSceneManager.SaveScene(EditorSceneManager.GetActiveScene(), scenePath);
        EditorUtility.DisplayDialog("DateTimePicker", "Demo Scene created: " + scenePath, "OK");
    }

    static GameObject CreateUI(string name, Transform parent)
    {
        var go = new GameObject(name);
        var rt = go.AddComponent<RectTransform>();
        rt.localScale = Vector3.one;
        if (parent != null) go.transform.SetParent(parent, false);
        return go;
    }

    static GameObject CreateText(string name, string text, Transform parent)
    {
        var go = CreateUI(name, parent);
        var txt = go.AddComponent<Text>();
        txt.text = text;
        txt.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
        txt.color = Color.black;
        txt.alignment = TextAnchor.MiddleLeft;
        var rt = go.GetComponent<RectTransform>();
        rt.sizeDelta = new Vector2(160, 30);
        return go;
    }

    static GameObject CreateButton(string name, string label, Transform parent)
    {
        var go = CreateUI(name, parent);
        var img = go.AddComponent<Image>();
        img.color = new Color(0.85f, 0.85f, 0.85f);
        var btn = go.AddComponent<Button>();

        var txt = CreateText("Text", label, go.transform);
        var rt = go.GetComponent<RectTransform>();
        rt.sizeDelta = new Vector2(80, 30);
        var txtRt = txt.GetComponent<RectTransform>();
        txtRt.anchorMin = new Vector2(0, 0);
        txtRt.anchorMax = new Vector2(1, 1);
        txtRt.anchoredPosition = Vector2.zero;
        txt.GetComponent<Text>().alignment = TextAnchor.MiddleCenter;
        txt.GetComponent<Text>().fontSize = 16;

        return go;
    }
}